/**
 * 
 */
package org.bankabeule.ui.editors;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.bankabeule.Account;
import org.bankabeule.BankabeuleFactory;
import org.bankabeule.Model;
import org.bankabeule.Operation;
import org.bankabeule.OperationTypeEnum;
import org.bankabeule.Tag;
import org.bankabeule.core.ModelListener;
import org.bankabeule.core.ModelManager;
import org.bankabeule.ui.utils.Logger;
import org.bankabeule.ui.utils.OperationsTableListener;
import org.bankabeule.ui.utils.OperationsTableViewer;
import org.bankabeule.util.AccountAdapter;
import org.bankabeule.util.Providers;
import org.bankabeule.util.Utils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.part.EditorPart;

/**
 * @author sdudoit
 *
 */
public class AccountEditor extends EditorPart implements ModelListener {


	/**
	 * ID
	 */
	public static final String ID = "org.bankabeule.ui.editors.AccountEditor";

	/**
	 * Account
	 */
	private Account account = null;

	/**
	 * Operation form
	 */
	private Composite form;

	/**
	 * Operations table
	 */
	private OperationsTableViewer viewer;

	/**
	 * Status label
	 */
	private Label statusLabel;

	/**
	 * Account adapter
	 */
	private AccountAdapter accountAdapter;

	/**
	 * Operation edited
	 */
	private Operation operation;

	/**
	 * Tags
	 */
	private List<Tag> tags = new ArrayList<Tag>();

	/**
	 * Operation filters
	 */
	private Composite filters;

	/**
	 * Filter date
	 */
	private String dateFilter;

	/**
	 * Filter name
	 */
	private String nameFilter;

	/**
	 * Filter value
	 */
	private String valueFilter;

	/**
	 * Filter type
	 */
	private String typeFilter;

	/**
	 * Filter description
	 */
	private String descriptionFilter;

	/**
	 * Filter tags
	 */
	private final List<Tag> tagsFilter = new ArrayList<Tag>();

	/**
	 * Constructor
	 */
	public AccountEditor() {
		// register listener
		ModelManager.get().addModelListener(this);
	}


	@Override
	public void dispose() {
		if (this.getEditorInput() instanceof AccountEditorInput) {
			this.account = ((AccountEditorInput) this.getEditorInput()).getAccount();
			this.account.eAdapters().remove(this.accountAdapter);
		}
		// unregister listener
		ModelManager.get().removeModelListener(this);
		// dispose
		super.dispose();
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	public void doSave(IProgressMonitor monitor) {
		try {
			ModelManager.get().save();
		} catch (Exception e) {
			Logger.log(e);
		}
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
	 */
	@Override
	public void doSaveAs() {
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	@Override
	public void init(IEditorSite site, IEditorInput input)
	throws PartInitException {
		this.setSite(site);
		this.setInputWithNotify(input);
		if (input instanceof AccountEditorInput) {
			this.account = ((AccountEditorInput) input).getAccount();
			this.accountAdapter = new AccountAdapter() {
				@Override
				public void accountChanged(Account account) {
					AccountEditor.this.setPartName(Utils.getDisplay(account));
				}
			};
			this.account.eAdapters().add(this.accountAdapter);
			this.setPartName(Utils.getDisplay(this.account));
		} else {
			throw new PartInitException("No AccountEditorInput as input.");
		}
	}



	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.EditorPart#isDirty()
	 */
	@Override
	public boolean isDirty() {
		return ModelManager.get().isDirty();
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
	 */
	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public void createPartControl(Composite parent) {
		FormToolkit tk = new FormToolkit(parent.getDisplay());

		Composite main = tk.createComposite(parent);
		main.setLayout(new GridLayout(1, true));

		Section section = tk.createSection(main, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE);
		section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		section.setText("Edit");
		Composite sectionComposite = tk.createComposite(section);
		section.setClient(sectionComposite);
		sectionComposite.setLayout(new GridLayout(1, true));

		this.form = this.createForm(sectionComposite, tk);
		this.form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

		Section section2 = tk.createSection(main, ExpandableComposite.TITLE_BAR);
		section2.setText("List");
		section2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		Composite sectionComposite2 = tk.createComposite(section2);
		section2.setClient(sectionComposite2);

		this.viewer = new OperationsTableViewer(sectionComposite2);
		this.viewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		this.viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				if (event.getSelection() instanceof StructuredSelection) {
					Operation operation = (Operation) ((StructuredSelection) event.getSelection()).getFirstElement();
					AccountEditor.this.editOperation(operation);
				}
			}
		});
		this.viewer.addFilter(new ViewerFilter() {
			@Override
			public boolean select(Viewer v, Object parentElement,
					Object element) {
				Operation operation = (Operation) element;
				if (AccountEditor.this.dateFilter != null) {
					if (!Utils.getDisplay(operation.getDate()).contains(AccountEditor.this.dateFilter)) {
						return false;
					}
				}
				if (AccountEditor.this.nameFilter != null) {
					if (!operation.getName().contains(AccountEditor.this.nameFilter)) {
						return false;
					}
				}
				if (AccountEditor.this.valueFilter != null) {
					if (!Utils.getDisplay(operation.getValue()).contains(AccountEditor.this.valueFilter)) {
						return false;
					}
				}
				if (AccountEditor.this.typeFilter != null) {
					if (!operation.getType().getLiteral().equals(AccountEditor.this.typeFilter)) {
						return false;
					}
				}
				if (AccountEditor.this.descriptionFilter != null) {
					if (!operation.getDescription().contains(AccountEditor.this.descriptionFilter)) {
						return false;
					}
				}
				if (!AccountEditor.this.tagsFilter.isEmpty()) {
					for (Tag tag : AccountEditor.this.tagsFilter) {
						if (!operation.getTags().contains(tag)) {
							return false;
						}
					}
				}
				return true;
			}
		});

		List<Operation> operations = this.account.getOperations();
		this.statusLabel = tk.createLabel(sectionComposite2, "");
		this.statusLabel.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
		this.statusLabel.setText("(Nb operations: "+operations.size()
				+" - Sum: "+Utils.getDisplay(Utils.calculateSum(operations))+")");
		this.viewer.addOperationsTableListener(new OperationsTableListener() {
			public void refreshed() {
				TableItem[] items = AccountEditor.this.viewer.getTable().getItems();
				List<Operation> operations = new ArrayList<Operation>();
				for (TableItem item : items) {
					operations.add((Operation) item.getData());
				}
				AccountEditor.this.statusLabel.setText("(Nb operations: "+operations.size()
						+" - Sum: "+Utils.getDisplay(Utils.calculateSum(operations))+")");
			}
		});

		Section section3 = tk.createSection(main, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE);
		section3.setText("Filter");
		section3.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		Composite sectionComposite3 = tk.createComposite(section3);
		section3.setClient(sectionComposite3);
		sectionComposite3.setLayout(new GridLayout(1, true));

		this.filters = this.createFilters(sectionComposite3, tk);
		this.filters.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

		this.viewer.setInput(this.account);
		this.editOperation(null);
	}


	/**
	 * Create form panel
	 */
	private Composite createForm(Composite parent, FormToolkit tk) {
		Composite form = tk.createComposite(parent);
		GridLayout gridLayout = new GridLayout(4, false);
		gridLayout.marginWidth = 0;
		gridLayout.marginLeft = 0;
		gridLayout.marginRight = 0;
		gridLayout.marginTop = 0;
		gridLayout.marginBottom = 0;
		gridLayout.marginHeight = 0;
		gridLayout.verticalSpacing = 0;
		form.setLayout(gridLayout);

		KeyAdapter keyAdapter = new KeyAdapter(){
			@Override
			public void keyReleased(KeyEvent e) {
				if (e.stateMask == SWT.CTRL) {
					if (e.keyCode == 13) {
						try {
							AccountEditor.this.saveOperation();
							AccountEditor.this.editOperation(null);
						} catch(NumberFormatException ex) {
							MessageDialog.openError(AccountEditor.this.getSite().getShell(), "Error", "Bad value !");
						}
					}
				}
			}
		};

		// title
		Label label = tk.createLabel(form, "");
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1));

		// date
		DateTime date = new DateTime(form, SWT.NONE);
		date.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));

		// name
		Text text = tk.createText(form, "<Name>", SWT.SEARCH | SWT.CANCEL);
		text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("<Name>")) {
					((Text)e.getSource()).setText("");
				}
			}
		});
		text.addKeyListener(keyAdapter);

		// value
		text = tk.createText(form, "0.0", SWT.RIGHT | SWT.SEARCH | SWT.CANCEL);
		GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false);
		gridData.widthHint = 100;
		text.setLayoutData(gridData);
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("0.0")) {
					((Text)e.getSource()).setText("");
				}
			}
		});
		text.addKeyListener(keyAdapter);

		// reset
		Button resetButton = tk.createButton(form, " Reset ", SWT.PUSH);
		resetButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		resetButton.addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				AccountEditor.this.editOperation(null);
			}
		});

		// type
		Combo combo = new Combo(form, SWT.NONE);
		combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		for (OperationTypeEnum value : OperationTypeEnum.values()) {
			combo.add(value.getLiteral(), value.getValue());
		}
		combo.select(OperationTypeEnum.POS_VALUE);

		// description
		text = tk.createText(form, "<Description>", SWT.SEARCH | SWT.CANCEL);
		text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("<Description>")) {
					((Text)e.getSource()).setText("");
				}
			}
		});
		text.addKeyListener(keyAdapter);

		// tags
		Button tagsButton = tk.createButton(form, " Edit tags ... ", SWT.PUSH);
		gridData = new GridData(SWT.FILL, SWT.CENTER, false, false);
		gridData.widthHint = 100;
		tagsButton.setLayoutData(gridData);
		tagsButton.addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(AccountEditor.this.getSite().getShell(),
						Providers.getLabelProvider(), (ITreeContentProvider) Providers.getContentProvider()) {
					@Override
					protected TreeViewer createTreeViewer(
							Composite parent) {
						TreeViewer viewer = super.createTreeViewer(parent);
						viewer.expandAll();
						return viewer;
					}
				};
				dialog.setInitialElementSelections(AccountEditor.this.tags);
				dialog.setInput(ModelManager.get().getModel());
				dialog.addFilter(new ViewerFilter() {
					@Override
					public boolean select(Viewer viewer, Object parentElement,
							Object element) {
						return element instanceof Tag;
					}
				});
				if (dialog.open() == Window.OK) {
					for (Object o : dialog.getResult()) {
						AccountEditor.this.tags.add((Tag) o);
					}
				}
			}
		});

		// save
		Button saveButton = tk.createButton(form, " Save ", SWT.PUSH);
		saveButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		saveButton.addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				try {
					AccountEditor.this.saveOperation();
				} catch(NumberFormatException ex) {
					MessageDialog.openError(AccountEditor.this.getSite().getShell(), "Error", "Bad value !");
				}
			}
		});

		return form;
	}



	/**
	 * Create filters panel
	 */
	private Composite createFilters(Composite parent, FormToolkit tk) {
		Composite filters = tk.createComposite(parent);
		GridLayout gridLayout = new GridLayout(4, false);
		gridLayout.marginWidth = 0;
		gridLayout.marginLeft = 0;
		gridLayout.marginRight = 0;
		gridLayout.marginTop = 0;
		gridLayout.marginBottom = 0;
		gridLayout.marginHeight = 0;
		gridLayout.verticalSpacing = 0;
		filters.setLayout(gridLayout);

		// date
		Text text = tk.createText(filters, "<Filter date>", SWT.SEARCH | SWT.CANCEL);
		GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false);
		gridData.widthHint = 80;
		text.setLayoutData(gridData);
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("<Filter date>")) {
					((Text)e.getSource()).setText("");
				}
			}
			@Override
			public void focusLost(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("")) {
					((Text)e.getSource()).setText("<Filter date>");
				}
			}
		});
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = ((Text)e.getSource()).getText();
				if ((!text.equals("<Filter date>")) && (!text.equals(""))) {
					AccountEditor.this.dateFilter = text;
				} else {
					AccountEditor.this.dateFilter = null;
				}
				AccountEditor.this.viewer.refresh();
			}
		});

		// name
		text = tk.createText(filters, "<Filter name>", SWT.SEARCH | SWT.CANCEL);
		text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("<Filter name>")) {
					((Text)e.getSource()).setText("");
				}
			}
			@Override
			public void focusLost(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("")) {
					((Text)e.getSource()).setText("<Filter name>");
				}
			}
		});
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = ((Text)e.getSource()).getText();
				if ((!text.equals("<Filter name>")) && (!text.equals(""))) {
					AccountEditor.this.nameFilter = text;
				} else {
					AccountEditor.this.nameFilter = null;
				}
				AccountEditor.this.viewer.refresh();
			}
		});

		// value
		text = tk.createText(filters, "<Filter value>", SWT.RIGHT | SWT.SEARCH | SWT.CANCEL);
		gridData = new GridData(SWT.FILL, SWT.CENTER, false, false);
		gridData.widthHint = 100;
		text.setLayoutData(gridData);
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("<Filter value>")) {
					((Text)e.getSource()).setText("");
				}
			}
			@Override
			public void focusLost(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("")) {
					((Text)e.getSource()).setText("<Filter value>");
				}
			}
		});
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = ((Text)e.getSource()).getText();
				if ((!text.equals("<Filter value>")) && (!text.equals(""))) {
					AccountEditor.this.valueFilter = text;
				} else {
					AccountEditor.this.valueFilter = null;
				}
				AccountEditor.this.viewer.refresh();
			}
		});

		// reset
		Button resetButton = tk.createButton(filters, " Reset ", SWT.PUSH);
		resetButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		resetButton.addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				AccountEditor.this.tagsFilter.clear();
				Control[] controls = AccountEditor.this.filters.getChildren();
				((Text) controls[0]).setText("<Filter date>");
				((Text) controls[1]).setText("<Filter name>");
				((Text) controls[2]).setText("<Filter value>");
				((Combo) controls[4]).select(0);
				((Text) controls[5]).setText("<Filter description>");
			}
		});

		// type
		Combo combo = new Combo(filters, SWT.NONE);
		combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		combo.add("<Filter type>");
		for (OperationTypeEnum value : OperationTypeEnum.values()) {
			combo.add(value.getLiteral());
		}
		combo.select(0);
		combo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = ((Combo)e.getSource()).getText();
				if (!text.equals("<Filter type>")) {
					AccountEditor.this.typeFilter = text;
				} else {
					AccountEditor.this.typeFilter = null;
				}
				AccountEditor.this.viewer.refresh();
			}
		});

		// description
		text = tk.createText(filters, "<Filter description>", SWT.SEARCH | SWT.CANCEL);
		text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		text.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("<Filter description>")) {
					((Text)e.getSource()).setText("");
				}
			}
			@Override
			public void focusLost(FocusEvent e) {
				String text = ((Text)e.getSource()).getText();
				if (text.equals("")) {
					((Text)e.getSource()).setText("<Filter description>");
				}
			}
		});
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = ((Text)e.getSource()).getText();
				if ((!text.equals("<Filter description>")) && (!text.equals(""))) {
					AccountEditor.this.descriptionFilter = text;
				} else {
					AccountEditor.this.descriptionFilter = null;
				}
				AccountEditor.this.viewer.refresh();
			}
		});

		// tags
		Button tagsButton = tk.createButton(filters, " Filter tags ... ", SWT.PUSH);
		gridData = new GridData(SWT.FILL, SWT.CENTER, false, false);
		gridData.widthHint = 100;
		tagsButton.setLayoutData(gridData);
		tagsButton.addSelectionListener(new SelectionAdapter(){
			@Override
			public void widgetSelected(SelectionEvent e) {
				ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(AccountEditor.this.getSite().getShell(),
						Providers.getLabelProvider(), (ITreeContentProvider) Providers.getContentProvider()) {
					@Override
					protected TreeViewer createTreeViewer(
							Composite parent) {
						TreeViewer viewer = super.createTreeViewer(parent);
						viewer.expandAll();
						return viewer;
					}
				};
				dialog.setInitialElementSelections(AccountEditor.this.tagsFilter);
				dialog.setInput(ModelManager.get().getModel());
				dialog.addFilter(new ViewerFilter() {
					@Override
					public boolean select(Viewer viewer, Object parentElement,
							Object element) {
						return element instanceof Tag;
					}
				});
				if (dialog.open() == Window.OK) {
					for (Object o : dialog.getResult()) {
						AccountEditor.this.tagsFilter.add((Tag) o);
					}
					AccountEditor.this.viewer.refresh();
				}
			}
		});

		// empty label
		tk.createLabel(filters, "");

		return filters;
	}


	/**
	 * Edit operation
	 */
	private void editOperation(Operation operation) {
		this.operation = operation;
		Control[] controls = this.form.getChildren();
		if (operation == null) {
			((Label) controls[0]).setText("Edit a new operation.");
			Calendar calendar = Calendar.getInstance();
			DateTime date = (DateTime) controls[1];
			date.setDay(calendar.get(Calendar.DAY_OF_MONTH));
			date.setMonth(calendar.get(Calendar.MONTH) + 1);
			date.setYear(calendar.get(Calendar.YEAR));
			((Text) controls[2]).setText("<Name>");
			((Text) controls[3]).setText("0.0");
			((Combo) controls[5]).select(OperationTypeEnum.POS_VALUE);
			((Text) controls[6]).setText("<Description>");
			this.tags.clear();
		} else {
			((Label) controls[0]).setText("Edit existing operation"
					+ (operation.getId().equals("") ? "" : " ["+operation.getId()+"]."));
			DateTime date = (DateTime) controls[1];
			date.setDay(operation.getDate().getDay());
			date.setMonth(operation.getDate().getMonth() - 1);
			date.setYear(operation.getDate().getYear());
			((Text) controls[2]).setText(operation.getName());
			((Text) controls[3]).setText(Utils.getDisplay(operation.getValue()));
			((Combo) controls[5]).select(operation.getType().getValue());
			((Text) controls[6]).setText(operation.getDescription());
			this.tags = operation.getTags();
		}
	}


	/**
	 * Save operation
	 */
	private void saveOperation() throws NumberFormatException {
		Control[] controls = this.form.getChildren();
		// check value field
		double value = Double.parseDouble(((Text) controls[3]).getText().replace(',', '.'));
		// continue if valid value
		if (this.operation == null) {
			this.operation = BankabeuleFactory.eINSTANCE.createOperation();
			this.operation.setDate(BankabeuleFactory.eINSTANCE.createDate());
			this.account.getOperations().add(this.operation);
		}
		// get value
		this.operation.setId("");
		DateTime date = (DateTime) controls[1];
		this.operation.getDate().setDay(date.getDay());
		this.operation.getDate().setMonth(date.getMonth() + 1);
		this.operation.getDate().setYear(date.getYear());
		String name = ((Text) controls[2]).getText();
		this.operation.setName(name.equals("<Name>") ? "" : name);
		this.operation.setValue(value);
		this.operation.setType(OperationTypeEnum.valueOf(((Combo) controls[5]).getText()));
		String description = ((Text) controls[6]).getText();
		this.operation.setDescription(description.equals("<Description>") ? "" : description);
		// recalculate account value
		Utils.calculateValue(this.account);
		// set tags
		this.operation.getTags().addAll(this.tags);
		this.viewer.refresh();
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
	 */
	@Override
	public void setFocus() {
		this.viewer.getControl().setFocus();
	}


	public void modelDirty(Model model) {
		this.firePropertyChange(IEditorPart.PROP_DIRTY);
	}


	public void modelSaved(Model model) {
		this.firePropertyChange(IEditorPart.PROP_DIRTY);
	}


	public void modelLoaded(Model model) {
	}


	public void modelUnloaded(Model model) {
	}


}
